package com.huawei.java.main;

import java.io.*;
import java.util.*;

/**
 * 面向对象重构代码
 * Server类、VM类
 * Server类：
 * 其中维护一个List，表示该服务器中运行的虚拟机
 * ServerList，当前已经购买的Server
 * 用ArrayList存储，用hashMap做缓存，方便检索
 */
public class Main {
    /**
     * 服务器资源类
     */
    static class Server implements Comparable<Server> {
        private final int serverId;//服务器id，从0开始
        private int A_Core;//A剩余的cpu数量
        private int B_Core;//B剩余的cpu数量
        private int A_Memory;//A剩余的memory
        private int B_Memory;//B剩余的memory
        private int allResource;
        /**
         * 资源剩余率
         * 计算方法：
         * (A_core + B_core) * 100/CoresInit + (A_Memory + B_Memory) * 100/MemoriesInit
         */
        private int rate;//资源剩余率
        private final int CoresInit;//初始cpu数量
        private final int MemoriesInit;//初始内存容量
        private final List<String> vmList;//在该服务器上运行的虚拟机


        public Server(int serverId, Integer[] integers) {
            this.serverId = serverId;
            //integers 信息如下
            //A cores，B cores，A memory，B memory，price,电费
            this.A_Core = integers[0];
            this.B_Core = integers[1];
            this.A_Memory = integers[2];
            this.B_Memory = integers[3];

            this.CoresInit = integers[0] + integers[1];
            this.MemoriesInit = integers[2] + integers[3];
            this.rate = (this.A_Core + this.B_Core) * 100 / this.CoresInit +
                    (this.A_Memory + this.B_Memory) * 100 / this.MemoriesInit;
            this.allResource = this.A_Core + this.B_Core + this.A_Memory + this.B_Memory;
            this.vmList = new ArrayList<>();
        }

        //返回当前服务器中所有资源的总量（核心+内存）
        private void updateRate() {
            this.rate = (this.A_Core + this.B_Core) * 100 / this.CoresInit +
                    (this.A_Memory + this.B_Memory) * 100 / this.MemoriesInit;
        }

        @Override
        public int compareTo(Server o) {
            if (this.rate == o.rate) {
                return 0;
            } else if (this.rate > o.rate) {
                return 1;
            } else {
                return -1;
            }
        }
    }

    static class ServerInfo implements Comparable<ServerInfo> {
        String serverName;
        int cores;
        int memories;
        int price;
        int powerCost;
        double performance;

        public ServerInfo(String serverName, int cores, int memories,
                          int price, int powerCost, double performance) {
            this.serverName = serverName;
            this.cores = cores;
            this.memories = memories;
            this.price = price;
            this.powerCost = powerCost;
            this.performance = performance;
        }

        @Override
        public int compareTo(ServerInfo o) {
            if (this.performance == o.performance) {
                return 0;
            } else if (this.performance > o.performance) {
                return 1;
            } else {
                return -1;
            }
        }
    }

    //可购买入服务器信息
    HashMap<String, Integer[]> serverInfoMap = new HashMap<>(100);
    ArrayList<ServerInfo> performanceList = new ArrayList<>(100);
    //可购卖出的虚拟机信息
    HashMap<String, Integer[]> vmInfoMap = new HashMap<>(1000);

    //服务器资源
    ArrayList<Server> serverList = new ArrayList<>(50000);
    //通过serverId 获得对应的  服务器
    HashMap<Integer, Server> serverResourceMap = new HashMap<>(50000);
    //通过VmId获得其宿主机(服务器)
    HashMap<String, Server> vmOnServer = new HashMap<>(50000);
    //通过VmId获得虚拟机类型
    HashMap<String, String> vmNumToType = new HashMap<>(500000);
    HashMap<String, Integer> vmNumToNode = new HashMap<>(500000);//是否双节点部署,0->双节点，1->A,2->B

    //剩余请求天数
    int lastDay = 0;

    //在运行的虚拟机总数量
    int vmTotalNum = 0;

    //服务器编号
    int serverNum = 0;
    //性价比最优的服务器名称
    String betterServerName = "";
    //每天请求中最大需求的core、memory
    double todayMaxCore = 0;
    double todayMaxMemory = 0;
    //每天请求的全局保存
    ArrayList<String[]> todayRequestList = new ArrayList<>(200);
    //每天购买服务器  输出信息的全局保存
    ArrayList<String> todayBuyServerList = new ArrayList<>(200);
    //每天虚拟机分配  输出信息的全局保存
    ArrayList<String> todayDeployVmList = new ArrayList<>(200);
    ArrayList<String> todayMigrateOut = new ArrayList<>(300);

    public Boolean match(String[] request, int targetServerNum) {
        //完成迁移操作之后，再次将其排序，先使用 剩余率 低的服务器
        if (targetServerNum == -1) {
            Collections.sort(serverList);
            boolean res;
            if (request[0].equals("add")) {
                res = addVm(request[1], request[2]);
            } else {
                res = delVm(request[1]);
            }
            return res;
        } else {
            return addVmToTarget(request[1], request[2], targetServerNum);
        }
    }

    public Boolean addVm(String vmType, String vmNum) {
        for (int i = 0; i < serverNum; i++) {
            //从排序后的列表，从满的开始找
            Server server = serverList.get(i);
            Integer[] info = vmInfoMap.get(vmType);
            if (chooseServer(server.serverId, info, vmNum)) {
                return true;
            }
        }
        return false;
    }

    public Boolean addVmToTarget(String vmType, String vmNum, int targetServerNum) {
        Server server = serverList.get(targetServerNum);
        Integer[] info = vmInfoMap.get(vmType);
        return chooseServer(server.serverId, info, vmNum);
    }

    public Boolean delVm(String vmNum) {
        // info数组: [core,memory,isTwoNode]
        Integer[] info = vmInfoMap.get(vmNumToType.get(vmNum));
        Server server = vmOnServer.get(vmNum);
        int node = vmNumToNode.get(vmNum);
        //分节点
        if (node == 0) {
            //双节点
            server.A_Core += info[0] >> 1;
            server.B_Core += info[0] >> 1;
            server.A_Memory += info[1] >> 1;
            server.B_Memory += info[1] >> 1;
            server.allResource += (info[0] + info[1]);
        } else if (node == 1) {
            //A节点
            server.A_Core += info[0];
            server.A_Memory += info[1];
            server.allResource += (info[0] + info[1]);
        } else {
            //B节点
            server.B_Core += info[0];
            server.B_Memory += info[1];
            server.allResource += (info[0] + info[1]);
        }
        //更新server的rate
        server.updateRate();
        //删除server中存储的Vm列表中的元素
        server.vmList.removeIf(s -> s.equals(vmNum));
        //vmNum -->server映射中删除
        vmOnServer.remove(vmNum);
        vmNumToNode.remove(vmNum);
        //虚拟机数量--
        vmTotalNum--;
        return true;
    }

    public Boolean chooseServer(Integer serverId, Integer[] info, String vmNum) {
        int vmCores = info[0];
        int vmMemory = info[1];
        int vmTwoNodes = info[2];

        Server server = serverResourceMap.get(serverId);
        if (vmTwoNodes == 1) {
            //双节点部署
            int needCores = vmCores >> 1;
            int needMemory = vmMemory >> 1;

            if (server.A_Core >= needCores &&
                    server.A_Memory >= needMemory &&
                    server.B_Core >= needCores &&
                    server.B_Memory >= needMemory) {
                //双节点部署成功，更新状态
                server.A_Core -= needCores;
                server.B_Core -= needCores;
                server.A_Memory -= needMemory;
                server.B_Memory -= needMemory;

                server.allResource -= (vmCores + vmMemory);
                String outPut = "(" + serverId + ")";
                todayDeployVmList.add(outPut);
                //更新资源剩余率
                server.updateRate();
                //VmNum ---> server 的映射
                vmOnServer.put(vmNum, server);
                //server中运行的服务器
                server.vmList.add(vmNum);
                //在运行的虚拟机+1
                vmTotalNum++;

                vmNumToNode.put(vmNum, 0);
                return true;

            } else {
                //该服务区双节点部署失败，返回false
                return false;
            }
        } else if (server.A_Core >= vmCores && server.A_Memory >= vmMemory) {
            //单节点部署——>先从A节点部署
            server.A_Core -= vmCores;
            server.A_Memory -= vmMemory;
            server.allResource -= (vmCores + vmMemory);
            String outPut = "(" + serverId + ", A)";
            todayDeployVmList.add(outPut);
            //更新资源剩余率
            server.updateRate();
            //VmNum ---> server 的映射
            vmOnServer.put(vmNum, server);
            //server中运行的服务器
            server.vmList.add(vmNum);
            //在运行的虚拟机+1
            vmTotalNum++;

            vmNumToNode.put(vmNum, 1);
            return true;
        } else if (server.B_Core >= vmCores && server.B_Memory >= vmMemory) {
            //单节点部署——>部署到B节点
            server.B_Core -= vmCores;
            server.B_Memory -= vmMemory;
            server.allResource -= (vmCores + vmMemory);
            String outPut = "(" + serverId + ", B)";
            todayDeployVmList.add(outPut);
            //更新资源剩余率
            server.updateRate();
            //VmNum ---> server 的映射
            vmOnServer.put(vmNum, server);
            //server中运行的服务器
            server.vmList.add(vmNum);
            //在运行的虚拟机+1
            vmTotalNum++;
            vmNumToNode.put(vmNum, 2);
            return true;
        }
        return false;
    }

    /**
     * 读取可以购买的服务器信息
     * 1.将服务器信息存入serverInfoMap
     * 2.将服务器按性价比排序，存入performanceList
     *
     * @param bufferedReader 输入流
     */
    public void readServer(BufferedReader bufferedReader) {
        try {
            int serverNum = Integer.parseInt(bufferedReader.readLine());
            //读取可以买入的服务器信息
            for (int i = 0; i < serverNum; i++) {
                String server = bufferedReader.readLine();
                String[] s = server.substring(1, server.length() - 1).split(", ");
                int cores = Integer.parseInt(s[1]);
                int memories = Integer.parseInt(s[2]);
                int price = Integer.parseInt(s[3]);
                int powerCost = Integer.parseInt(s[4]);

                //A cores，B cores，A memory，B memory，price,电费
                Integer[] info = new Integer[]{
                        cores >> 1,
                        cores >> 1,
                        memories >> 1,
                        memories >> 1,
                        price,
                        powerCost};
                //key--服务器名称，value--服务器信息
                serverInfoMap.put(s[0], info);
                //计算该服务器的性价比
                //TODO 计算性价比的公式可以进行优化，CM为cup/memory
                double performance = (price + 0.0) / (cores + memories);
                //加入服务器列表中进行排序
                performanceList.add(new ServerInfo(s[0], cores, memories, price, powerCost, performance));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 读取可以卖出的虚拟机数量
     * 1.将可以购买的虚拟机信息存入vmInfoMap
     * @param bufferedReader 文件输入流
     * @throws IOException
     */
    private void readVm(BufferedReader bufferedReader) throws IOException {
        int vmNum = Integer.parseInt(bufferedReader.readLine());
        for (int i = 0; i < vmNum; i++) {
            String vm = bufferedReader.readLine();
            String[] s = vm.substring(1, vm.length() - 1).split(", ");
            int VmCore = Integer.parseInt(s[1]);
            int VmMemory = Integer.parseInt(s[2]);
            int isTwoNode = Integer.parseInt(s[3]);
            Integer[] info = new Integer[]{VmCore, VmMemory, isTwoNode};
            vmInfoMap.put(s[0], info);
        }
    }

    /**
     * 计算该天的请求总资源量，包括cpu和memory
     * @param requestNum     请求数
     * @param bufferedReader 输入流
     * @return 包含  cpu总请求数和memory总请求数的数组
     * @throws IOException
     */
    private void dayRequest(int requestNum, BufferedReader bufferedReader) throws IOException {
        int totalCoreRequest = 0;
        int totalMemoRequest = 0;

        int coreRequest = 0;
        int memoryRequest = 0;
        int VmType = 0;
        for (int num = 0; num < requestNum; num++) {
            String line = bufferedReader.readLine();
            String[] opts = line.substring(1, line.length() - 1).split(", ");
            //将请求保存起来
            todayRequestList.add(opts);
            //只统计本天请求中add类型
            if (opts[0].equals("add")) {
                Integer[] info = vmInfoMap.get(opts[1]);
                coreRequest = info[0];
                memoryRequest = info[1];
                VmType = info[2];
                //VmId --->  VmType 映射
                vmNumToType.put(opts[2], opts[1]);
                //记录当天所有的需求量
                totalCoreRequest += coreRequest;
                totalMemoRequest += memoryRequest;
                //记录当天最大的需求量
                if (VmType == 0) {
                    //单节点部署
                    todayMaxCore = Math.max(todayMaxCore, coreRequest);
                    todayMaxMemory = Math.max(todayMaxMemory, memoryRequest);
                } else {
                    //双节点部署
                    todayMaxCore = Math.max(todayMaxCore, (coreRequest + 0.0) / 2);
                    todayMaxMemory = Math.max(todayMaxMemory, (memoryRequest + 0.0) / 2);
                }
            }
        }
    }

    /**
     * 根据当日请求，计算当日应该购买的服务器
     *
     * @param needCore   需要的cpu
     * @param needMemory 需要的memory
     */
    private void buyTodayServer(int needCore, int needMemory) {
        int minCost = Integer.MAX_VALUE;
        String serverName = "";
        int buyNum = 0;
        //选择买哪个服务器
        for (int i = 0, len = performanceList.size(); i < len; i++) {
            ServerInfo serverInfo = performanceList.get(i);
            int A_core = serverInfo.cores >> 1;
            int A_memory = serverInfo.memories >> 1;
            //不满足要求的直接跳过
            if (A_core < todayMaxCore || A_memory < todayMaxMemory)
                continue;
            //修改：以该服务器为目标凑数,找出花钱最少的一台服务器型号，买它！
            int a = needCore / serverInfo.cores + 1;
            int b = needMemory / serverInfo.memories + 1;
            int num = Math.max(a, b);
            //修改：考虑电费的因素，以剩余天数作为参数考量
            int cost = num * serverInfo.price + num * lastDay * serverInfo.powerCost;
            if (cost < minCost) {
                serverName = serverInfo.serverName;
                buyNum = num;
                minCost = cost;
            }
        }
        //暂存购买信息，之后在统一输出
        todayBuyServerList.add("(" + serverName + ", " + buyNum + ")");
        //给服务器编号,并保存到 Resource——>当前服务器状态中
        for (int i = 0; i < buyNum; i++) {
            Integer[] integers = serverInfoMap.get(serverName);
            Server addServer = new Server(serverNum, integers);
            serverList.add(addServer);
            //map快速索引
            serverResourceMap.put(serverNum, addServer);
            serverNum++;
        }
    }
    private void preProccess() {
        boolean thisProccess;
        while (!todayRequestList.isEmpty()) {
            String[] request = todayRequestList.get(0);
            thisProccess = match(request, -1);
            if (thisProccess) {
                //分配该条请求成功，从列表中删除
                todayRequestList.remove(0);
                continue;
            }
            //出现分配失败的情况
            //1.统计剩余请求的情况
            int[] requestNeed = dayLastRequest(todayRequestList);
            // 2.需要购买一组服务器
            int targetSeverNum = serverNum;
            buyTodayServer(requestNeed[0], requestNeed[1]);
            //3.再次分配这个请求
            thisProccess = match(request, targetSeverNum);
            //断言，一定能分配成功
            assert thisProccess;
            todayRequestList.remove(0);
        }
    }

    private void infoOutput() {
        //购买信息
        System.out.println("(purchase, " + todayBuyServerList.size() + ")");
        for (String s : todayBuyServerList) {
            System.out.println(s);
        }
        //迁移信息
        System.out.println("(migration, " + todayMigrateOut.size() + ")");
        for (String out : todayMigrateOut) {
            System.out.println(out);
        }
        //分配信息
        for (String s : todayDeployVmList) {
            System.out.println(s);
        }
        //输出完成后，清空当天的全局输出信息List
        todayBuyServerList.clear();
        todayDeployVmList.clear();
        todayMigrateOut.clear();
    }


    /**
     * 统计剩余请求的资源情况
     * @param lastRequestList 剩余请求的数据
     * @return
     */
    private int[] dayLastRequest(ArrayList<String[]> lastRequestList) {
        int totalCoreRequest = 0;
        int totalMemoRequest = 0;
        todayMaxCore = 0;
        todayMaxMemory = 0;

        int coreRequest = 0;
        int memoryRequest = 0;
        int VmType = 0;
        for (String[] opts : lastRequestList) {
            //只统计本天请求中add类型
            if (opts[0].equals("add")) {
                Integer[] infos = vmInfoMap.get(opts[1]);
                coreRequest = infos[0];
                memoryRequest = infos[1];
                VmType = infos[2];

                //记录当天所有的需求量
                totalCoreRequest += coreRequest;
                totalMemoRequest += memoryRequest;

                //记录当天最大的需求量
                if (VmType == 0) {
                    //单节点部署
                    todayMaxCore = Math.max(todayMaxCore, coreRequest);
                    todayMaxMemory = Math.max(todayMaxMemory, memoryRequest);
                } else {
                    //双节点部署
                    todayMaxCore = Math.max(todayMaxCore, (coreRequest + 0.0) / 2);
                    todayMaxMemory = Math.max(todayMaxMemory, (memoryRequest + 0.0) / 2);
                }
            }
        }
        return new int[]{totalCoreRequest, totalMemoRequest};
    }

    public void migrate() {
        //对当前的服务器按资源剩余率从小到大排序
        Collections.sort(serverList);
        //能迁移的虚拟机台数
        int number = vmTotalNum * 3 / 1000;

        /**
         * 遍历迁移的思路：
         * 1.从serverList尾部取出  资源剩余率  最大  的服务器，fromServer
         * 2.从fromServer服务器取出每个虚拟机，vmNum
         * 3.从serverList头部取出  资源剩余率  最小  的服务器 ，toServer
         * 4.尝试将vmNum分配给 toServer
         */
        int len = serverList.size();
        int len1 = (int) (len * 0.8);
        search:
        for (int i = serverList.size() - 1; i >= len1; i--) {
            Server fromServer = serverList.get(i);
            //无虚拟机
            if (fromServer.rate == 200) continue;
            for (int j = 0; j < fromServer.vmList.size(); j++) {
                if (number <= 0) {
                    //直接结束，跳出最外层循环
                    break search;
                }
                //准备迁移的虚拟机信息
                String vmNum = fromServer.vmList.get(j);
                String vmType = vmNumToType.get(vmNum);
                Integer[] info = vmInfoMap.get(vmType);

                int len2 = (int) (len * 0.7);
                for (int k = len2; k < i; k++) {
                    Server toServer = serverList.get(k);
                    //资源剩余率小于5
                    if (toServer.rate <= 5) {
                        continue;
                    }
                    if (checkMigrate(toServer, info, fromServer, vmNum)) {
                        //删除server中存储的Vm列表中的元素
                        fromServer.vmList.remove(j);
                        number--;
                        //因为改动了vmList，所以此处调用j--
                        j--;
                        break;
                    }
                }
            }
        }
    }

    /**
     * 恢复迁出虚拟机的资源
     *
     * @param fromServer 迁出虚拟机
     */
    public void recoveryServer(Server fromServer, String vmNum, int vmCores, int vmMemory) {
        Integer isTwoNode = vmNumToNode.get(vmNum);
        if (isTwoNode == 0) {
            //双节点部署
            int needCores = vmCores >> 1;
            int needMemory = vmMemory >> 1;
            //双节点
            fromServer.A_Core += needCores;
            fromServer.B_Core += needCores;
            fromServer.A_Memory += needMemory;
            fromServer.B_Memory += needMemory;
            fromServer.allResource += (vmCores + vmMemory);
            fromServer.updateRate();
        } else if (isTwoNode == 1) {
            //A节点
            fromServer.A_Core += vmCores;
            fromServer.A_Memory += vmMemory;
            fromServer.allResource += (vmCores + vmMemory);
            fromServer.updateRate();
        } else {
            //B节点
            fromServer.B_Core += vmCores;
            fromServer.B_Memory += vmMemory;
            fromServer.allResource += (vmCores + vmMemory);
            fromServer.updateRate();
        }
    }

    /**
     * 检查VmType类型虚拟机是否可以迁移到serverId好服务器
     * 在判断是否可迁移的步骤中，直接进行了迁移操作
     *
     * @param toServer 目标服务器
     * @param vmNum    需要迁移的虚拟机
     * @return 是否可迁移
     */
    public boolean checkMigrate(Server toServer, Integer[] info, Server fromServer, String vmNum) {
        int vmCores = info[0];
        int vmMemory = info[1];
        int vmTwoNodes = info[2];
        /**
         * 迁移分为两步：
         * 1.从from节点删除虚拟机
         * 2.在to节点加入虚拟机
         */
        if (vmTwoNodes == 1) {
            //双节点部署
            int needCores = vmCores >> 1;
            int needMemory = vmMemory >> 1;
            if (toServer.A_Core >= needCores &&
                    toServer.A_Memory >= needMemory &&
                    toServer.B_Core >= needCores &&
                    toServer.B_Memory >= needMemory) {
                //在to节点中加入虚拟机
                toServer.A_Core -= needCores;
                toServer.B_Core -= needCores;
                toServer.A_Memory -= needMemory;
                toServer.B_Memory -= needMemory;

                toServer.allResource -= (vmCores + vmMemory);
                //更新资源剩余率
                toServer.updateRate();

                //恢复服务器资源
                recoveryServer(fromServer, vmNum, vmCores, vmMemory);

                //VmNum ---> server 的映射
                vmOnServer.put(vmNum, toServer);
                //server中运行的服务器
                toServer.vmList.add(vmNum);
                vmNumToNode.put(vmNum, 0);
                //输出语句
                todayMigrateOut.add("(" + vmNum + ", " + toServer.serverId + ")");
                return true;
            } else {
                //该服务区双节点部署失败，返回false
                return false;
            }
        } else if (toServer.A_Core >= vmCores && toServer.A_Memory >= vmMemory) {
            //单节点部署——>部署到A节点
            //在to节点中加入虚拟机
            toServer.A_Core -= vmCores;
            toServer.A_Memory -= vmMemory;
            toServer.allResource -= (vmCores + vmMemory);

            //更新资源剩余率
            toServer.updateRate();

            //恢复服务器资源
            recoveryServer(fromServer, vmNum, vmCores, vmMemory);

            //VmNum ---> server 的映射
            vmOnServer.put(vmNum, toServer);
            //server中运行的服务器
            toServer.vmList.add(vmNum);
            vmNumToNode.put(vmNum, 1);
            //输出语句
            todayMigrateOut.add("(" + vmNum + ", " + toServer.serverId + ", A" + ")");
            return true;
        } else if (toServer.B_Core >= vmCores && toServer.B_Memory >= vmMemory) {
            //单节点部署——>部署到B节点
            //在to节点中加入虚拟机
            toServer.B_Core -= vmCores;
            toServer.B_Memory -= vmMemory;
            toServer.allResource -= (vmCores + vmMemory);
            //更新资源剩余率
            toServer.updateRate();
            //恢复服务器资源
            recoveryServer(fromServer, vmNum, vmCores, vmMemory);
            //VmNum ---> server 的映射
            vmOnServer.put(vmNum, toServer);
            //server中运行的服务器
            toServer.vmList.add(vmNum);
            vmNumToNode.put(vmNum, 2);
            //输出语句
            todayMigrateOut.add("(" + vmNum + ", " + toServer.serverId + ", B" + ")");
            return true;
        }
        return false;
    }

    public void start() throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        //读取服务器信息,并对性价比进行排序
        readServer(bufferedReader);
        //按照性价比进行排序
        Collections.sort(performanceList);
        //读取虚拟机信息，存入vmInfoMap
        readVm(bufferedReader);
        try {
            //读取总共有多少天的请求
            String[] line = bufferedReader.readLine().split(" ");
            int T = Integer.parseInt(line[0]);
            int K = Integer.parseInt(line[1]);
            for (int i = 0; i < T; i++) {
                lastDay = T - i;
                migrate();
                int requestNum = Integer.parseInt(bufferedReader.readLine());//当天的请求数
                //每天请求中最大需求的core、memory
                todayMaxCore = 0;
                todayMaxMemory = 0;
                //返回的request是当天请求的总量，核心和内存
                dayRequest(requestNum, bufferedReader);
                //直接开始预处理，预处理不成功则购买一批，知道当天所有请求被处理完毕。
                preProccess();
                //统一信息输出，包括购买、迁移、和分配
                infoOutput();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void startTest() throws Exception {
        String path = "C:\\Users\\Micah\\Desktop\\华为软件精英挑战\\training-data\\training-1.txt";
        File file = new File(path);
        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));

        //读取服务器信息,并对性价比进行排序
        readServer(bufferedReader);
        //按照性价比进行排序
        Collections.sort(performanceList);

        //读取虚拟机信息，存入vmInfoMap
        readVm(bufferedReader);
        //读取总共有多少天的请求
        String[] line = bufferedReader.readLine().split(" ");
        int T = Integer.parseInt(line[0]);
        int K = Integer.parseInt(line[1]);
        /**
         *   1.读取K天的数据
         *   2.输出第一天决策信息
         *   3.读取K+1天请求
         */
        for (int i = 0; i < T; i++) {
            lastDay = T - i;
            migrate();
            int requestNum = Integer.parseInt(bufferedReader.readLine());//当天的请求数
            //每天请求中最大需求的core、memory
            todayMaxCore = 0;
            todayMaxMemory = 0;
            //返回的request是当天请求的总量，核心和内存
            dayRequest(requestNum, bufferedReader);
            //直接开始预处理，预处理不成功则购买一批，知道当天所有请求被处理完毕。
            preProccess();
            //统一进行购买信息的输出
            infoOutput();
        }
    }

    public static void main(String[] args) throws Exception {
        new Main().startTest();
    }
}